#ifndef SERVER_INITIAL_H
#define SERVER_INITIAL_H

#include <iostream>
#include <vector>
#include <mutex>
#include <condition_variable>
extern "C"{
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <cstring>
    #include <sys/epoll.h>
}


#define LINE    15
#define LIST    15

// typedef int ;
typedef int SOCK;       //自定义一个套接字的类型

using namespace std;

//存储用户数据的结构体
struct playdata{
    SOCK cilentfd;  //在用户登录前，用户套接字连接后赋值
    string name;    //在用户登录或注册后赋值
    int win;        //在用户登录或注册后赋值
};

class room
{
public:
    int id; //房间的id，在创建房间是赋值一般代表是第几个房间
    // mutex latch;
    // unique_lock<mutex> action(latch);
    // condition_variable wait_for_gec;
    int chessboard[LINE * LIST];    //棋盘的数据
    playdata* host;     //主场的用户，执黑棋
    playdata* gec;      //客场的用户，执白棋
    int epwatch;        //监听观战者的epoll描述符
    vector<playdata*> watcher;      //存储观战用户的数据
    //创建房间的构造函数，主场和房间id得在创建时赋值
    room(playdata* host,int id):host(host),id(id),gec(nullptr){
        epwatch = epoll_create(10);
        if (-1 == epwatch)
        {
            cout << "创建epoll描述符失败" << endl;
            return ;
        }
    }
    friend void epoll_watchers(room* watcher);
    void add_watcher(playdata* arg);
    bool del_watcher(playdata* arg);
    void create_pthread();
    bool send_data(playdata* arg);
    void monitor();
    void game_over(){
        delete this;
    }
};

//服务端的数据存储总类
class Data{
private:
public:
    mutex latch;        //对服务器数据进行修改时的互斥锁
    vector<room*> vol;  //存储房间的容器
    int room_num;       //创建的房间数
    static Data& get_Data(){
        static Data main_data;
        return main_data;
    }
    void traverse(char * room_id);
    room* traverse(int room_id = 0);
    void create_room(playdata * host);
    ~Data(){};
private:
    Data(){}
    Data(const Data& p){}
};


//创建并返回被监听的套接字
int sock_initial();



#endif